package com.pool.net;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;

import com.pool.common.Lists;
import com.pool.common.Maps;

/**
 * Provides a way to communicate with Google Spreadsheet through the GData API.
 * 
 * @author claveld@gmail.com (David Clavel)
 */
public class SpreadsheetsConnector {

  private static final String CLIENT_LOGIN_URL = "https://www.google.com/accounts/ClientLogin";
  
  private static final String EMAIL_KEY = "Email";
  private static final String PASSWORD_KEY = "Passwd";
  private static final String SERVICE_KEY = "service";
  private static final String ACCOUNT_TYPE_KEY = "accountType";
  private static final String SOURCE_KEY = "source";
  
  private static SpreadsheetsConnector instance = null;
  
  public static SpreadsheetsConnector get() {
    if (instance == null) {
      instance = new SpreadsheetsConnector();
    }
    return instance;
  }
  
  public HttpResponse doGet(String authKey, String tableUrl) {
    HttpClient httpClient = new DefaultHttpClient();
    HttpGet httpGet = new HttpGet(tableUrl);
    httpGet.addHeader("Authorization", "GoogleLogin auth=" + authKey);
    HttpResponse response = null;
    try {
      response = httpClient.execute(httpGet);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return response;
  }

  public HttpResponse doPost(String authKey, String tableUrl, String data) {
    HttpClient httpClient = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost(tableUrl);
    httpPost.addHeader("Content-Type", "application/atom+xml");
    httpPost.addHeader("Authorization", "GoogleLogin auth=" + authKey);
    HttpResponse response = null;
    try {
      StringEntity httpEntity = new StringEntity(data, HTTP.UTF_8);
      httpPost.setEntity(httpEntity);
      response = httpClient.execute(httpPost);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return response;
  }
  
  public String authenticate(String email, String password) {
    HttpClient httpClient = new DefaultHttpClient();
    
    HttpPost httpPost = new HttpPost(CLIENT_LOGIN_URL);
    List<BasicNameValuePair> nvps = Lists.newArrayList();
    nvps.add(new BasicNameValuePair(EMAIL_KEY, email));
    nvps.add(new BasicNameValuePair(PASSWORD_KEY, password));
    nvps.add(new BasicNameValuePair(SERVICE_KEY, "wise"));
    nvps.add(new BasicNameValuePair(ACCOUNT_TYPE_KEY, "GOOGLE"));
    nvps.add(new BasicNameValuePair(SOURCE_KEY, "AndroidPoolStanding"));
 
    try {
      UrlEncodedFormEntity httpEntity = new UrlEncodedFormEntity(nvps, HTTP.UTF_8);
      
      httpPost.setEntity(httpEntity);
      HttpResponse response = httpClient.execute(httpPost);
      HttpEntity responseEntity = response.getEntity();
      
      Map<String, String> result = getAuthResponse(responseEntity);
      return result.get("Auth");
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }
  
  private static Map<String, String> getAuthResponse(HttpEntity httpEntity) {
    Map<String, String> response = Maps.newHashMap();
    
    try {
      BufferedReader br = new BufferedReader(new InputStreamReader(httpEntity.getContent()));
      String line = "";
      while ((line = br.readLine()) != null) {
        int delimiterPosition = line.indexOf("=");
        String key = line.substring(0, delimiterPosition);
        String value = line.substring(delimiterPosition + 1);
        response.put(key, value);
      }
    } catch (Exception e) {
      return null;
    }
    return response;
  }
}
